package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.exception.LogicException;
import cn.wolfcode.wolf2w.query.User;
import cn.wolfcode.wolf2w.redis.service.IUserInfoRedisService;
import cn.wolfcode.wolf2w.redis.util.RedisKeys;
import cn.wolfcode.wolf2w.repository.UserInfoRepository;
import cn.wolfcode.wolf2w.service.IUserInfoService;
import cn.wolfcode.wolf2w.util.AssertUtil;
import cn.wolfcode.wolf2w.util.Consts;
import cn.wolfcode.wolf2w.util.JsonResult;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
//@Transactional
public class UserInfoServiceImpl implements IUserInfoService {

    //操作MongoDB数据库
    @Autowired
    private UserInfoRepository userInfoRepository;

    //操作Redis数据库
    @Autowired
    private IUserInfoRedisService userInfoRedisService;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Override
    public void save(UserInfo userInfo) {
        userInfoRepository.save(userInfo);
    }

    @Override
    public void delete(String id) {
        userInfoRepository.deleteById(id);
    }

    @Override
    public void update(UserInfo userInfo) {
        userInfoRepository.save(userInfo);
    }

    @Override
    public UserInfo findByOne(String id) {
        return userInfoRepository.findById(id).orElse(null);
    }

    @Override
    public List<UserInfo> findAll() {
        return userInfoRepository.findAll();
    }

    //短信验证码发送
    @Override
    public JsonResult VerifyCode(String phone) {
        //创建验证码
        String code = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 4);
        //创建短信信息
        StringBuilder note = new StringBuilder(80);
        note.append("您的验证码:").append(code).append(",请在").append(Consts.VERIFY_CODE_VAI_TIME).append("分钟进行验证");
        System.out.println(note);

        //发送短信
        /*RestTemplate template = new RestTemplate();*/
        /**
         * Url:https://way.jd.com/BABO/sms?mobile=15000000000&msg=【巴卜技术】您的验证码是201422,若非本人操作请忽略&appkey=ac7e1ea95f54724769d98ecd335b195b
         *
         */
        /*String url="https://way.jd.com/BABO/sms?mobile={1}&msg=【叩丁狼】{2}&appkey={3}";
        String appkey = "ac7e1ea95f54724769d98ecd335b195b";
        String ret = template.getForObject(url, String.class, phone, note.toString(), appkey);
        System.out.println(ret);
        if (!ret.contains("msgid")) {
            throw new LogicException("短信发送失败");
        }*/

        //往redis里面存储
        redisTemplate.opsForValue().set(RedisKeys.VERIFY_CODE.join(phone),code,Consts.VERIFY_CODE_VAI_TIME*60, TimeUnit.SECONDS);
        return JsonResult.success();
    }

    //登录
    @Override
    public JsonResult login(User user) {
        //非空处理
        AssertUtil.hasLength("用户名或密码不能为空",user.getUsername(),user.getPassword());
        //根据用户名和密码查询数据库(MongoDB数据库)
        UserInfo userInfo = userInfoRepository.queryByPhoneAndPassword(user.getUsername(),user.getPassword());
        System.out.println(userInfo);
        //userInfo对象为空抛逻辑异常
        AssertUtil.hasObject("用户名或密码错误",userInfo);
        //将token存到Redis数据库中
        String token = userInfoRedisService.setToken(userInfo);
        //提供前端需要的数据(token和当前对象)
        Map map = new HashMap();
        //将对象转换成JSON格式(如果前端做了,后端就不用做了)
        map.put("user", userInfo);
        map.put("token",token);
        return JsonResult.success(map);
    }

    //注册
    @Override
    public JsonResult regist(UserInfo user, String rpassword, String verifyCode) {
        //非空处理
        AssertUtil.hasLength("呢成不能为空",user.getNickname());
        AssertUtil.hasLength("密码不能为空",user.getPassword());
        AssertUtil.hasLength("确认密码不能为空",rpassword);
        AssertUtil.hasLength("验证码不能为空",verifyCode);
        //判断密码和确认密码是否正确
        AssertUtil.esEquals("密码和确认密码不一致",user.getPassword(),rpassword);
        //判断手机号格式
        AssertUtil.checkPhone(user.getPhone());
        //验证码检验
        //获取存进redis里面的key
        String code = redisTemplate.opsForValue().get(RedisKeys.VERIFY_CODE.join(user.getPhone()));
        System.out.println(RedisKeys.VERIFY_CODE + user.getPhone());
        AssertUtil.esEquals("验证码失效或不正确",code,verifyCode);
        //注册
        //初始化用户参数
        user.setEmail("");
        user.setCity("");
        user.setHeadImgUrl("/images/default.jpg");
        user.setInfo("");
        user.setState(UserInfo.STATE_NORMAL);

        //模拟系统出现异常(不让用户看到系统的异常信息)
//        throw new RuntimeException("s;dljfl;jasdfljsadl;jflkasjdfljasdl;jflksjadlkj;asdlk;fj");
        userInfoRepository.save(user);

        return JsonResult.success();
    }

    //判断手机号是否可以注册
    @Override
    public boolean checkPhone(String phone) {
        //判断手机号格式
        AssertUtil.checkPhone(phone);
        UserInfo user = userInfoRepository.queryByPhone(phone);
        return user==null;
    }

    @Override
    public List<String> queryUserFavorList(String userId) {
        List<String> sidList = new ArrayList<>();
        //拼接key
        String uidKey = RedisKeys.USER_FAVOR.join(userId);
        //判断是否存在key
        if (redisTemplate.hasKey(uidKey)) {
            //存在查询数据库
            String sidsStr = redisTemplate.opsForValue().get(uidKey);
            sidList=JSON.parseArray(sidsStr,String.class);
        }
        return sidList;
    }
}
